package com.analyse.stock.utils;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;

import java.math.BigDecimal;
import java.time.LocalTime;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class StockStringUtil {
    public static final String regex = "^\\{.*\\}$|^\\[.*\\]$";

    public static final Function<LocalTime,Boolean> tradingTimeFun = (localTime) -> {
        LocalTime startTime1 = LocalTime.of(9, 30);
        LocalTime endTime1 = LocalTime.of(11, 30);
        LocalTime startTime2 = LocalTime.of(13, 0);
        LocalTime endTime2 = LocalTime.of(15, 0);
        boolean b1 = localTime.isAfter(startTime1) && localTime.isBefore(endTime1);
        boolean b2 = localTime.isAfter(startTime2) && localTime.isBefore(endTime2);
        return b1 || b2;
    };

    /**
     * 打榜时间点,早盘集合竞价时间
     *
     * 集合竞价挂单成交规则:
     * 【1】集合竞价遵守价格、时间、数量优先原则。庄家的单是9：15进入交易所系统的，9：15至9：25挂的单有时间顺序按时间优先。
     * 【2】在这个时候，集合竟价没成交的单到连续竟价时还有时间优先，同一时间的，按数量优先。
     * 【3】有的证券公司可以提前挂单，一般是在9：15以后开始进入交易所系统，此后的单都会在同一时间进入交易所系统，数量大的先成交。
     *
     * 9.15 ~ 9.20   可挂单，可撤单，不进行撮合交易
     * 9.20 ~ 9.25   可挂单，不可撤单，撮合交易
     * 9.25 ~ 9.30   不可挂单，不可撤单，不进行撮合交易
     */
    public static final Function<LocalTime,Boolean> topRankTradingTimeFun = (localTime) -> {
        LocalTime startTime1 = LocalTime.of(9, 15);
        LocalTime endTime1 = LocalTime.of(9, 30);
        return localTime.isAfter(startTime1) && localTime.isBefore(endTime1);
    };

    /**
     * 尾盘集合竞价时间
     * 14:57 ~ 15.00   可挂单，不可撤单，进行撮合交易
     */
    public static final Function<LocalTime,Boolean> downTradingTimeFun = (localTime) -> {
        LocalTime startTime1 = LocalTime.of(9, 15);
        LocalTime endTime1 = LocalTime.of(9, 30);
        return localTime.isAfter(startTime1) && localTime.isBefore(endTime1);
    };

    public static Function<LocalTime,Boolean> getTradingTimeFun(String localOpenTime,String localCloseTime){
        int openHour = DateUtil.hour(DateUtil.parse(localOpenTime, DatePattern.NORM_TIME_FORMAT),true);
        int openMinute = DateUtil.minute(DateUtil.parse(localOpenTime, DatePattern.NORM_TIME_FORMAT));
        int closeHour = DateUtil.hour(DateUtil.parse(localCloseTime, DatePattern.NORM_TIME_FORMAT),true);
        int closeMinute = DateUtil.minute(DateUtil.parse(localCloseTime, DatePattern.NORM_TIME_FORMAT));
        return (localTime) -> {
            LocalTime startTime1 = LocalTime.of(openHour, openMinute);
            LocalTime endTime1 = LocalTime.of(openHour+2, openMinute);
            LocalTime startTime2 = LocalTime.of(closeHour-2, closeMinute);
            LocalTime endTime2 = LocalTime.of(closeHour, closeMinute);
            boolean b1 = localTime.isAfter(startTime1) && localTime.isBefore(endTime1);
            boolean b2 = localTime.isAfter(startTime2) && localTime.isBefore(endTime2);
            return b1 || b2;
        };
    }

    public static <T> T getObject(String str,Class<T> clz){
        if(StringUtils.isBlank(str)){
            return null;
        }
        try {
            return JSONObject.parseObject(str,clz);
        } catch (JSONException e) {

        }
        return null;
    }
    public static <T> List<T> getArray(String str,Class<T> clz){
        if(StringUtils.isBlank(str)){
            return null;
        }
        try {
            return JSONObject.parseArray(str,clz);
        } catch (JSONException e) {

        }
        return null;
    }

    public static List<Integer> getAllYear(String beginDate){
        List<Integer> years = Lists.newArrayList();
        int currentYear = DateUtil.year(new Date());
        int offYear = DateUtil.year(DateUtil.parseDate(beginDate));
        while (offYear<=currentYear){
            years.add(offYear);
            DateTime dateTime = DateUtil.offset(DateUtil.parseDate(String.format("%s-01-01",offYear)), DateField.YEAR,1);
            offYear = DateUtil.year(dateTime);
        }
        return years.stream().sorted(Comparator.comparing(Integer::intValue)).collect(Collectors.toList());
    }

    public static BigDecimal getDecimalValue(String val){
        val = StringUtils.defaultIfBlank(val,"0");
        if("-".equalsIgnoreCase(val)){
            val = "0";
        }
        return new BigDecimal(val);
    }

    public static <E> String join(String delimiter, Iterable<? extends CharSequence> elements){
        if(!elements.iterator().hasNext()){
            return "";
        }
        return String.join(delimiter, elements);
    }
    public static void main(String[] args) {
        List<String> fl = Lists.newArrayList();
        for(int i =1 ;i<101;i++){
            fl.add(String.format("f%d",i));
        }
        System.out.println(String.join(StrUtil.COMMA,fl));
    }
}
